package com.hyper_yang._05_juc.chap02;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReentrantReadWriteLock;


/**
 * synchronized 具备原子性。互斥锁、排他锁、独占锁
 */
//资源类
class MyCache {

    private ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock(); //默认 非公平锁     true公平锁
    private Map<String, String> cache = new HashMap<>();

    //写  写写不可并发     读写/写读 不可并发
    public void put(String key, String value) {
        readWriteLock.writeLock().lock(); //加写锁
        try {
            System.out.println(Thread.currentThread().getName() + " 开始写入！");
            Thread.sleep(300);
            cache.put(key, value);
            System.out.println(Thread.currentThread().getName() + " 写入成功！");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            readWriteLock.writeLock().unlock(); //解除写锁
        }
    }

    //读      读读可并发
    public void get(String key) {
        readWriteLock.readLock().lock(); //加读锁
        try {
            System.out.println(Thread.currentThread().getName() + " 开始读出！");
            Thread.sleep(300);
            String value = cache.get(key);
            System.out.println(Thread.currentThread().getName() + " 读出成功！" + value);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            readWriteLock.readLock().unlock(); //释放读锁
        }
    }
}

public class ReentrantReadWriteLockDemo {

    public static void main(String[] args) {

        MyCache cache = new MyCache();

        for (int i = 1; i <= 5; i++) {
            String num = String.valueOf(i);
            // 开启5个写线程
            new Thread(() -> {
                cache.put(num, num);
            }, "A-" + num).start();
        }

        for (int i = 1; i <= 5; i++) {
            String num = String.valueOf(i);
            // 开启5个读线程
            new Thread(() -> {
                cache.get(num);
            }, "B-" + num).start();
        }
    }
}